package org.yx.service.smfr.pass_product_sn;

import java.util.List;

import org.dbist.dml.Query;
import org.yx.exception.BizException;
import org.yx.models.*;
import org.yx.service.bas.view_common_data_setup_detail.BasViewCommonDataSetupDetailIn;
import org.yx.service.bas.view_common_data_setup_detail.BasViewCommonDataSetupDetailService;
import org.yx.service.smfr.insert_product_serial_history.SmfrInsertProductSerialHistoryIn;
import org.yx.service.smfr.insert_product_serial_history.SmfrInsertProductSerialHistoryService;
import org.yx.utils.BaseService;
import org.yx.utils.FieldMap;
import org.yx.utils.ServiceBeanUtil;

import com.xiaoleilu.hutool.collection.CollUtil;
import com.xiaoleilu.hutool.util.NumberUtil;
import com.xiaoleilu.hutool.util.StrUtil;

/**
 * 产品批次工序过站
 *
 * @author zxw
 * @since 2019/04/20
 **/
public class SmfrPassProductSnService extends BaseService {
    public SmfrPassProductSnOut passProductSn(SmfrPassProductSnIn in) throws Exception {
        checkStringNotBlank(in, "mo,psn,oper");

        if (StrUtil.isNotBlank(in.getResId())) {
            SresDevDef devDef = selectWithPk(SresDevDef.class, in.getUserOrgCode(), in.getResId());
            if (devDef == null || 'D' == devDef.getResStatus()) {
                throw new BizException("SRES-0001", "此资源${resId}不存在或已经删除。", FieldMap.of("resId", in.getResId()));
            }
        }

        SmfrOrdDef order = selectWithPk(SmfrOrdDef.class, in.getUserOrgCode(), in.getMo());
        if (order == null || "D".equals(order.getMoStatus())) {
            throw new BizException("SMFR-0004", "生产工单${mo}不存在或已被删除。", FieldMap.of("mo", in.getMo()));
        }

        if (!"P".equals(order.getMoStatus())) {
            throw new BizException("SMFR-0008", "当生产工单${mo}的状态是${moStatus}，此操作是无效的。", FieldMap.of("mo", order.getMo()),
                    FieldMap.of("moStatus", order.getMoStatus()));
        }

        if (StrUtil.isBlank(order.getPathCode())) {
            throw new BizException("SMFR-0009", "生产工单${mo}的工艺路线或工序不存在。", FieldMap.of("mo", order.getMo()));
        }

        if (!StrUtil.equals(order.getLineCode(), in.getLineCode())) {
            throw new BizException("SMFR-0011", "此生产订单${mo}不属于此生产线${lineCode}。", FieldMap.of("mo", order.getMo()),
                    FieldMap.of("lineCode", in.getLineCode()));
        }

        SmfrPsnSts psnSts = selectOneLocked(SmfrPsnSts.class, order.getOrgCode(), in.getPsn());
        if (psnSts == null || "D".equals(psnSts.getStatus())) {
            throw new BizException("SMFR-0010", "产品批号${psn}不存在或已删除。", FieldMap.of("psn", in.getPsn()));
        }
        if ("C".equals(psnSts.getStatus())) {// Create status
            psnSts.setStatus("P");// Process status
        }

        if (!"P".equals(psnSts.getStatus()) && !"S".equals(psnSts.getStatus())) {
            BasViewCommonDataSetupDetailIn cdsIn = new BasViewCommonDataSetupDetailIn();
            cdsIn.setGroupName("PSN_EVENT");
            cdsIn.setKey1(psnSts.getEventCode());
            List<MbasCdsDtl> cdsDtlList = ServiceBeanUtil.getBean(BasViewCommonDataSetupDetailService.class)
                    .viewCommonDataSetupDetail(cdsIn).getCdsDtlList();
            String eventDesc = CollUtil.isNotEmpty(cdsDtlList) ? cdsDtlList.get(0).getData1() : "";
            cdsIn.setGroupName("PSN_STATUS");
            cdsIn.setKey1(psnSts.getStatus().toString());
            cdsDtlList = ServiceBeanUtil.getBean(BasViewCommonDataSetupDetailService.class)
                    .viewCommonDataSetupDetail(cdsIn).getCdsDtlList();
            String psnStatusDesc = CollUtil.isNotEmpty(cdsDtlList) ? cdsDtlList.get(0).getData1() : "";

            throw new BizException("SMFR-0012", "产品批号${psn}在状态${status}以及事件${event}下，当前操作不允许。", FieldMap.of("psn",
                    psnSts.getPsn()), FieldMap.of("status", psnSts.getStatus() + "(" + psnStatusDesc + ")"),
                    FieldMap.of("event", psnSts.getEventCode() + "(" + eventDesc + ")"));
        }

        if (StrUtil.isNotBlank(in.getOper()) && !StrUtil.equals(in.getOper(), psnSts.getOper())) {
            throw new BizException("SMFR-0015", "产品批号${psn}当前工序是${oper}。", FieldMap.of("psn", psnSts.getPsn()),
                    FieldMap.of("oper", psnSts.getOper()));
        }

        SmfrProPth path = selectWithPk(SmfrProPth.class, order.getOrgCode(), order.getPathCode());
        if (path == null || 'D' == path.getPathStatus()) {
            throw new BizException("SMFR-0002", "工艺路线${pathCode}不存在或已经删除。",
                    FieldMap.of("pathCode", order.getPathCode()));
        }

        Query query = new Query();
        query.addFilter("orgCode", order.getOrgCode());
        query.addFilter("pathCode", path.getPathCode());
        query.addFilter("status", 'N');
        query.addOrder("seqNum", true);
        List<SmfrPthOpr> operList = selectList(SmfrPthOpr.class, query);
        if (CollUtil.isEmpty(operList)) {
            throw new BizException("SMFR-0005", "工艺路线${pathCode}的工序不存在。", FieldMap.of("pathCode", path.getPathCode()));
        }

        int currOperIndex = -1;
        for (int i = 0; i < operList.size(); i++) {
            if (operList.get(i).getSeqNum().equals(psnSts.getOperSeq())
                    && operList.get(i).getOper().equals(psnSts.getOper())) {
                currOperIndex = i;
                break;
            }
        }

        if (currOperIndex < 0) {
            throw new BizException("SMFR-0013", "产品批号${psn}无法匹配到当前工序${oper}的信息。", FieldMap.of("psn", psnSts.getPsn()),
                    FieldMap.of("oper", psnSts.getOper()));
        } else {
            SmfrOprDef oper = selectWithPk(SmfrOprDef.class, operList.get(currOperIndex).getOrgCode(), operList.get(currOperIndex)
                    .getOper());
            if (oper == null || oper.getOperStatus() == 'D') {
                throw new BizException("SMFR-0001", "工序${oper}不存在或已经删除。", FieldMap.of("oper", operList.get(currOperIndex)
                        .getOper()));
            } else if ('H' == oper.getOperStatus()) {
                throw new BizException("SMFR-0014", "工序${oper}当前状态是品质锁定状态。", FieldMap.of("oper", oper.getOper()));
            }

            SmfrOprDef nextOper = null;

            psnSts.setMo(order.getMo());
            psnSts.setMatCode(order.getMatCode());
            psnSts.setMatVer(order.getMatVer());
            psnSts.setDtlSeq(psnSts.getDtlSeq() + 1);
            psnSts.setPathCode(path.getPathCode());
            psnSts.setQty(in.getQty() == null ? psnSts.getQty() : in.getQty());
            psnSts.setEventCode("MOVE");//通过本工序时记为MOVE
            psnSts.setEventValue("TRIG");
            psnSts.setCurrentLoc(order.getLineCode());
            psnSts.setResId(in.getResId());
            if (currOperIndex == operList.size() - 1) {
                // 最后一道工序过站只增工序序列，不变工序
                psnSts.setStatus("F");
            }
            //记录本工序信息并通过
            update(psnSts, "mo,matCode,matVer,status,dtlSeq,operSeq,oper,pathCode,qty,eventCode,eventValue,currentLoc,resId");

            SmfrInsertProductSerialHistoryIn hisIn = new SmfrInsertProductSerialHistoryIn();
            hisIn.setPsnSts(psnSts);
            ServiceBeanUtil.getBean(SmfrInsertProductSerialHistoryService.class).insertProductSerialHistory(hisIn);

            if (currOperIndex < operList.size() - 1) {
                //移到下一工序
                nextOper = selectWithPk(SmfrOprDef.class, operList.get(currOperIndex + 1).getOrgCode(), operList.get(currOperIndex + 1).getOper());
                if (nextOper == null || nextOper.getOperStatus() == 'D') {
                    throw new BizException("SMFR-0001", "工序${oper}不存在或已经删除。", FieldMap.of("oper", operList.get(currOperIndex + 1)
                            .getOper()));
                } else if ('H' == nextOper.getOperStatus()) {
                    throw new BizException("SMFR-0014", "工序${oper}当前状态是品质锁定状态。", FieldMap.of("oper", nextOper.getOper()));
                }

                psnSts.setEventCode("WAIT");//由上工序推到此工序的，在新工序WAIT
                psnSts.setEventValue("TRIG");
                psnSts.setResId(null);
                psnSts.setDtlSeq(psnSts.getDtlSeq() + 1);
                psnSts.setOper(nextOper.getOper());
                psnSts.setOperSeq(operList.get(currOperIndex + 1).getSeqNum());
                psnSts.setPathCode(order.getPathCode());
                psnSts.setStatus("P");
                if ('Y' == nextOper.getStartEnd() && 'Y' != nextOper.getAutoMove()) {
                    psnSts.setStatus("S");
                }

                update(psnSts, "mo,matCode,matVer,status,dtlSeq,operSeq,oper,pathCode,qty,eventCode,eventValue,currentLoc,resId");

                hisIn = new SmfrInsertProductSerialHistoryIn();
                hisIn.setPsnSts(psnSts);
                ServiceBeanUtil.getBean(SmfrInsertProductSerialHistoryService.class).insertProductSerialHistory(hisIn);
            }

            // auto move oper
            if ("E".equals(psnSts.getStatus())) {
                while (!"F".equals(psnSts.getStatus())) {
                    // 查找条码后序工序是否自动过站
                    currOperIndex++;
                    if (currOperIndex > operList.size() - 1) {
                        break;
                    }
                    SmfrPthOpr pathOper = operList.get(currOperIndex);

                    nextOper = selectWithPk(SmfrOprDef.class, pathOper.getOrgCode(), pathOper.getOper());
                    if (nextOper == null || nextOper.getOperStatus() == 'D') {
                        throw new BizException("SMFR-0001", "工序${oper}不存在或已经删除。", FieldMap.of("oper", psnSts.getOper()));
                    } else if ('H' == nextOper.getOperStatus()) {
                        throw new BizException("SMFR-0014", "工序${oper}当前状态是品质锁定状态。", FieldMap.of("oper", psnSts.getOper()));
                    }

                    psnSts.setDtlSeq(psnSts.getDtlSeq() + 1);
                    psnSts.setEventCode("MOVE");
                    psnSts.setEventValue("AUTO");
                    psnSts.setOperSeq(pathOper.getSeqNum());
                    psnSts.setOper(pathOper.getOper());
                    psnSts.setStatus("P");
                    if (currOperIndex == operList.size() - 1) {
                        // 最后一道工序过站只增工序序列，不变工序
                        psnSts.setStatus("F");
                    }

                    if ('Y' != nextOper.getAutoMove()) {
                        psnSts.setStatus('Y' == nextOper.getStartEnd() ? "S" : "P");
                        psnSts.setEventValue("WAIT");
                    }

                    update(psnSts, "status,dtlSeq,operSeq,oper,eventCode,eventValue");

                    hisIn.setPsnSts(psnSts);
                    ServiceBeanUtil.getBean(SmfrInsertProductSerialHistoryService.class).insertProductSerialHistory(
                            hisIn);

                    if ('Y' != nextOper.getAutoMove()) {
                        break;
                    }
                }
            }

            if ("F".equals(psnSts.getStatus())) {
                //最后产品完工
                order.setOutQty(NumberUtil.add(order.getOutQty(), psnSts.getQty()));

                update(order, "outQty");
            }
        }

        return new SmfrPassProductSnOut();
    }
}